var Player = (function() {
    var instance;

    var newPlayer = function(el) {
        var mAudio = el;

        var current = 0;
        var locked = false;
        var order = [];
        var playlist = [];

        var getCurrent = function() {
            for (i = 0; i < playlist.length; i++) {
                if (playlist[i].id == order[current])
                    return playlist[i];
            }
        };

        var prep = function() {
            var song = getCurrent();
            mAudio.src = song.href;
            mAudio.title = song.title;
        };

        var play = function() {
            mAudio.play();
            Badge.getInstance().turnActive();
        };

        var pause = function() {
            mAudio.pause();
            Badge.getInstance().turnIdle();
        };

        var next = function(ended) {
            if ((current + 1) < playlist.length) {
                current++;
                if (!mAudio.paused) {
                    prep();
                    play();
                } else
                    prep();
            } else {
                if (ended) {
                    pause();
                    Badge.getInstance().turnIdle();
                }
            }
        };

        var stop = function() {
            current = 0;
            prep();
        };

        var load = function(urls) {
            if (!locked) {
                playlist = urls;
                order = [];
                for (i = 0; i < playlist.length; i++) {
                    order.push(playlist[i].id);
                }
                stop();
                Badge.getInstance().turnIdle();
            }
        };

        var prev = function() {
            if ((current - 1) >= 0) {
                current--;
                prep();
                if (!mAudio.paused)
                    play();
            }
        };

        var jump = function(id) {
            i = 0;
            while (i < order.length) {
                if (order[i] == id) {
                    current = i;
                    if (!mAudio.paused) {
                        prep();
                        play();
                    } else
                        prep();
                }
                i++;
            }
        };

        // Setup
        mAudio.addEventListener("ended", function(evt) {
            next(true);
        });

        return {
            load: load,
            prep: prep,
            play: play,
            pause: pause,
            stop: stop,
            next: next,
            prev: prev,
            jump: jump,
            lock: function() {
                locked = true;
            },
            unlock: function() {
                locked = false;
            },
            sort: function(order) {
                current = order[current];
                order = order;
                i = 0;
                while (i < order.length) {
                    if (order[i] == current) {
                        current = i;
                        i = order.length;
                    }
                    i++;
                }
            },
            getCurrent: getCurrent,
            isPaused: function() {
                return mAudio.paused;
            },
            isLocked: function() {
                return locked;
            },
            getDuration: function() {
                return mAudio.duration;
            },
            getCurrentTime: function() {
                return mAudio.currentTime;
            },
            addEventListener: function(event, callback) {
                mAudio.addEventListener(event, callback);
            },
            getPlaylist: function() {
                return playlist;
            },
            getCurrentPosition: function() {
                return current;
            },
            seek: function(perc) {
                mAudio.currentTime = perc * mAudio.duration / 100;
            }
        }
    };

    return {
        getInstance: function(el) {
            if (instance === undefined) {
                instance = newPlayer(el);
            }
            return instance;
        }
    }
})();